package com.yex.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.yex.base.Constant;
import com.yex.base.WalletOper;
import com.yex.base.WalletOperEnum;
import com.yex.base.ZeroResultException;
import com.yex.common.exception.RRException;
import com.yex.common.utils.DateUtil;
import com.yex.common.utils.PageUtils;
import com.yex.dao.InvestmentOrderDao;
import com.yex.dao.UserDao;
import com.yex.entity.*;
import com.yex.service.*;
import com.yex.utils.JsonResultVo;
import com.yex.utils.MathUtil;
import com.yex.utils.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;


@Service("investmentOrderService")
public class InvestmentOrderServiceImpl extends ServiceImpl<InvestmentOrderDao, InvestmentOrderEntity> implements InvestmentOrderService {
    @Autowired
    private WalletService walletService;
    @Autowired
    private InvestService investService;
    @Autowired
    private InvestmentService investmentService;
    @Autowired
    private LocaleMessageSourceService message;
    @Autowired
    private IntegralService integralService;
    @Autowired
    private RedemptionService redemptionService;
    @Autowired
    private UserService userService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private InvestmentLogService investmentLogService;
    @Autowired
    private DynamicService dynamicService;
    @Autowired
    private DynamicLogService dynamicLogService;
    @Autowired
    private UserDao userDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Page<InvestmentOrderEntity> page = this.selectPage(
                new Query<InvestmentOrderEntity>(params).getPage(),
                new EntityWrapper<InvestmentOrderEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional
    public JsonResultVo insertInvestmentOrder(String investmentId, String number, Integer userId) {

        InvestmentOrderEntity investmentOrderEntity = this.selectInvestmentOrderByInvestmentAndUser(Integer.valueOf(investmentId), userId);
        if (investmentOrderEntity != null) {
            throw new RRException("已经存在一个报单记录");
        }

        InvestmentEntity investmentEntity = investmentService.selectById(investmentId);
//        InvestEntity investEntity = investService.selectByUserId(userId);
        WalletEntity walletEntity = walletService.selectByUserId(userId);
        if (investmentEntity == null || walletEntity == null) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }
        InvestmentOrderEntity investmentOrder = new InvestmentOrderEntity();

        if (Constant.ONE_THOUSAND >= Integer.valueOf(number) && Integer.valueOf(number) < Constant.FIVE_THOUSAND) {
            investmentOrder.setInvest(new BigDecimal(Constant.ONE_HUNDRED + ""));
        } else if (Constant.FIVE_THOUSAND >= Integer.valueOf(number) && Integer.valueOf(number) < Constant.TEN_THOUSAND) {
            investmentOrder.setInvest(new BigDecimal(Constant.TWO_HUNDRED + ""));
        } else if (Constant.TEN_THOUSAND >= Integer.valueOf(number) && Integer.valueOf(number) < Constant.TWENTY_THOUSAND) {
            investmentOrder.setInvest(new BigDecimal(Constant.THREE_HUNDRED + ""));
        } else if (Constant.TWENTY_THOUSAND >= Integer.valueOf(number) && Integer.valueOf(number) < Constant.THIRTY_THOUSAND) {
            investmentOrder.setInvest(new BigDecimal(Constant.FOUR_HUNDRED + ""));
        } else if (Constant.THIRTY_THOUSAND >= Integer.valueOf(number)) {
            investmentOrder.setInvest(new BigDecimal(Constant.FIVE_HUNDRED + ""));
        }

        long days = DateUtil.spaceDays(investmentEntity.getEndTime(), investmentEntity.getStartTime());
        Calendar dayDate = DateUtil.getLaterDayDate(Integer.valueOf(days + ""));
        investmentOrder.setInvestmentId(investmentEntity.getId());
        investmentOrder.setUserId(userId);
        investmentOrder.setOrderId(0);
        investmentOrder.setNumber(new BigDecimal(number));
        investmentOrder.setStatus(0);
        investmentOrder.setEndTime(dayDate.getTime());
        investmentOrder.setStartTime(new Date());
        investmentOrder.setCreateTime(new Date());
        investmentOrder.setUpdateTime(new Date());
        Integer result = baseMapper.insert(investmentOrder);
        if (result <= 0) {
//            return new JsonResultVo(message.getMessage("fail"), -1);
            throw new RRException("报单失败");
        }

        WalletOper walletOper = new WalletOper();
        walletOper.setUserId(investmentOrder.getUserId());
        //  从number改为通证值,因为通证改为手续费
        walletOper.setAmount(investmentOrder.getInvest());
        walletOper.setRemark("报单数量");
        walletOper.setOper(WalletOperEnum.REDUCE);
        walletOper.setId(walletEntity.getId());
        walletService.updateWallet(walletOper);

//        WalletOper investOper = new WalletOper();
//        investOper.setUserId(userId);
//        investOper.setAmount(investmentOrder.getInvest());
//        investOper.setRemark("报单排单币");
//        investOper.setOper(WalletOperEnum.REDUCE);
//        investOper.setId(investEntity.getId());
//        investService.updateInvest(investOper);

        //  修改业务逻辑,改为减少用户余额
        UserEntity userEntity = userDao.selectById(investmentOrder.getUserId());
        userEntity.setTotal(BigDecimal.valueOf(Integer.valueOf(number)));
        Integer count = userDao.updateReduce(userEntity);
        if (count > 1) throw new RRException("报单失败");

        return new JsonResultVo(message.getMessage("success"));
    }

    @Override
    @Transactional
    public JsonResultVo updateInvestmentOrder(String investmentOrderId, String number, Integer userId) {

        InvestmentOrderEntity investmentOrderEntity = baseMapper.selectById(investmentOrderId);

        InvestmentEntity investmentEntity = investmentService.selectByOne();

        if (investmentOrderEntity == null || investmentEntity == null) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }

        if (investmentOrderEntity.getEndTime().getTime() > System.currentTimeMillis() || investmentOrderEntity.getStatus() == 1) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }

        Integer result = baseMapper.updateReplyByStatus(investmentOrderEntity.getId());
        if (result <= 0) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }

        InvestEntity investEntity = investService.selectByUserId(investmentOrderEntity.getUserId());
        WalletEntity walletEntity = walletService.selectByUserId(investmentOrderEntity.getUserId());


        InvestmentOrderEntity investmentOrder = new InvestmentOrderEntity();

        if (Constant.ONE_THOUSAND >= Integer.valueOf(number) && Integer.valueOf(number) < Constant.FIVE_THOUSAND) {
            investmentOrder.setInvest(new BigDecimal(Constant.ONE_HUNDRED + ""));
        } else if (Constant.FIVE_THOUSAND >= Integer.valueOf(number) && Integer.valueOf(number) < Constant.TEN_THOUSAND) {
            investmentOrder.setInvest(new BigDecimal(Constant.TWO_HUNDRED + ""));
        } else if (Constant.TEN_THOUSAND >= Integer.valueOf(number) && Integer.valueOf(number) < Constant.TWENTY_THOUSAND) {
            investmentOrder.setInvest(new BigDecimal(Constant.THREE_HUNDRED + ""));
        } else if (Constant.TWENTY_THOUSAND >= Integer.valueOf(number) && Integer.valueOf(number) < Constant.THIRTY_THOUSAND) {
            investmentOrder.setInvest(new BigDecimal(Constant.FOUR_HUNDRED + ""));
        } else if (Constant.THIRTY_THOUSAND >= Integer.valueOf(number)) {
            investmentOrder.setInvest(new BigDecimal(Constant.FIVE_HUNDRED + ""));
        }

        long days = DateUtil.spaceDays(investmentEntity.getEndTime(), investmentEntity.getStartTime());
        Calendar dayDate = DateUtil.getLaterDayDate(Integer.valueOf(days + ""));
        investmentOrder.setInvestmentId(investmentEntity.getId());
        investmentOrder.setUserId(investmentOrderEntity.getUserId());
        investmentOrder.setOrderId(investmentOrderEntity.getId());
        investmentOrder.setNumber(MathUtil.add(new BigDecimal(number), investmentOrderEntity.getNumber()));
        investmentOrder.setStatus(0);
        investmentOrder.setEndTime(dayDate.getTime());
        investmentOrder.setStartTime(new Date());
        investmentOrder.setCreateTime(new Date());
        investmentOrder.setUpdateTime(new Date());
        result = baseMapper.insert(investmentOrder);
        if (result <= 0) {
            throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
        }

        WalletOper walletOper = new WalletOper();
        walletOper.setUserId(investmentOrder.getUserId());
        walletOper.setAmount(investmentOrder.getNumber());
        walletOper.setRemark("报单数量");
        walletOper.setOper(WalletOperEnum.REDUCE);
        walletOper.setId(walletEntity.getId());
        walletService.updateWallet(walletOper);

        WalletOper investOper = new WalletOper();
        investOper.setUserId(investmentOrder.getUserId());
        investOper.setAmount(investmentOrder.getInvest());
        investOper.setRemark("报单排单币");
        investOper.setOper(WalletOperEnum.REDUCE);
        investOper.setId(investEntity.getId());
        investService.updateInvest(investOper);

        return new JsonResultVo(message.getMessage("success"));

    }


    @Override
    @Transactional
    public Integer updateAutoInvestment() {

        InvestmentEntity investmentEntity = investmentService.selectByOne();
        if (investmentEntity == null) {
            return 1;
        }

        List<InvestmentOrderEntity> orderList = baseMapper.selectExpireInterestOrderList(DateUtil.getBeforeHourDate(24).getTime());
        for (InvestmentOrderEntity investmentOrderEntity : orderList) {

            Integer result = baseMapper.updateAutoRedeemByStatus(investmentOrderEntity.getId());
            if (result <= 0) {
                return 1;
            }

            InvestmentOrderEntity investmentOrder = new InvestmentOrderEntity();
            investmentOrder.setInvest(BigDecimal.ZERO);
            long days = DateUtil.spaceDays(investmentEntity.getEndTime(), investmentEntity.getStartTime());
            Calendar dayDate = DateUtil.getLaterDayDate(Integer.valueOf(days + ""));
            investmentOrder.setInvestmentId(investmentEntity.getId());
            investmentOrder.setUserId(investmentOrderEntity.getUserId());
            investmentOrder.setOrderId(investmentOrderEntity.getId());
            investmentOrder.setNumber(investmentOrderEntity.getNumber());
            investmentOrder.setStatus(0);
            investmentOrder.setEndTime(dayDate.getTime());
            investmentOrder.setStartTime(new Date());
            investmentOrder.setCreateTime(new Date());
            investmentOrder.setUpdateTime(new Date());
            result = baseMapper.insert(investmentOrder);
            if (result <= 0) {
                throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
            }
        }
        return 1;
    }


    @Override
    @Transactional
    public JsonResultVo updateRedeemInvestmentOrder(String investmentOrderId, String type, Integer userId) {

        List<InvestmentOrderEntity> orderList = baseMapper.selectInvestmentOrderByUserId(userId);
        if (orderList.size() < 6) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }

        InvestmentOrderEntity investmentOrderEntity = baseMapper.selectById(investmentOrderId);
        if (investmentOrderEntity == null) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }
        InvestmentEntity investmentEntity = investmentService.selectById(investmentOrderEntity.getInvestmentId());

        if (investmentEntity == null) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }

        if (investmentOrderEntity.getEndTime().getTime() > System.currentTimeMillis() || investmentOrderEntity.getStatus() == 4) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }

        Integer result = baseMapper.updateRedeemByStatus(investmentOrderEntity.getId());
        if (result <= 0) {
            return new JsonResultVo(message.getMessage("fail"), -1);
        }

        if ("1".equals(type)) {

            IntegralEntity integralEntity = integralService.selectByUserId(investmentOrderEntity.getUserId());
            WalletOper oper = new WalletOper();
            oper.setUserId(investmentOrderEntity.getUserId());
            oper.setAmount(MathUtil.mul(investmentOrderEntity.getNumber(), investmentEntity.getRedeemIntegral()));
            oper.setRemark("赎回转商城积分");
            oper.setOper(WalletOperEnum.ADD);
            if (integralEntity != null) {
                oper.setId(integralEntity.getId());
            }
            integralService.updateIntegralt(oper);

        } else {
            WalletOper oper = new WalletOper();
            oper.setUserId(investmentOrderEntity.getUserId());
            oper.setAmount(MathUtil.mul(investmentOrderEntity.getNumber(), investmentEntity.getRedeemEtcc()));
            oper.setRemark("赎回转ETCC");
            oper.setOper(WalletOperEnum.FROZEN);
            walletService.updateAddFrozen(oper);
            RedemptionEntity redemptionEntity = new RedemptionEntity();
            redemptionEntity.setTotal(oper.getAmount());
            redemptionEntity.setUserId(investmentOrderEntity.getUserId());
            redemptionEntity.setOrderId(investmentOrderEntity.getId());
            redemptionEntity.setStatus(1);
            redemptionEntity.setType(2);
            redemptionEntity.setStartTime(DateUtil.getLaterDayDate(investmentEntity.getRedeemDay()).getTime());
            redemptionEntity.setRate(investmentEntity.getRedeemRate());
            redemptionEntity.setSuccessAmount(BigDecimal.ZERO);
            redemptionEntity.setCreateTime(new Date());
            redemptionEntity.setUpdateTime(new Date());
            if (!redemptionService.insert(redemptionEntity)) {
                throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
            }
        }
        return new JsonResultVo(message.getMessage("success"));
    }


    @Override
    public InvestmentOrderEntity selectInvestmentOrderByInvestmentAndUser(Integer investmentId, Integer userId) {
        return baseMapper.selectByUserId(investmentId, userId);
    }

    @Override
    @Transactional
    public Integer updateInvestmentOrder() {
        List<InvestmentOrderEntity> investmentOrderEntities = baseMapper.selectInterestOrderList();
        for (InvestmentOrderEntity investmentOrderEntity : investmentOrderEntities) {
            InvestmentEntity investmentEntity = investmentService.selectById(investmentOrderEntity.getInvestmentId());
            Integer result = baseMapper.updateInterestByStatus(investmentOrderEntity.getId());
            if (result <= 0) {
                throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
            }

            BigDecimal profitCash = MathUtil.mul(investmentOrderEntity.getNumber(), MathUtil.div(investmentEntity.getProfitCash(), new BigDecimal("100")));
            BigDecimal profitIntegral = MathUtil.mul(investmentOrderEntity.getNumber(), MathUtil.div(investmentEntity.getProfitIntegral(), new BigDecimal("100")));
            BigDecimal profitEtcc = MathUtil.mul(investmentOrderEntity.getNumber(), MathUtil.div(investmentEntity.getProfitEtcc(), new BigDecimal("100")));

            IntegralEntity integralEntity = integralService.selectByUserId(investmentOrderEntity.getUserId());
            WalletOper oper = new WalletOper();
            oper.setUserId(investmentOrderEntity.getUserId());
            oper.setAmount(profitIntegral);
            oper.setRemark("到期转商城积分");
            oper.setOper(WalletOperEnum.ADD);
            if (integralEntity != null) {
                oper.setId(integralEntity.getId());
            }
            integralService.updateIntegralt(oper);

            WalletOper operEtcc = new WalletOper();
            operEtcc.setUserId(investmentOrderEntity.getUserId());
            operEtcc.setAmount(profitEtcc);
            operEtcc.setRemark("到期转ETCC");
            operEtcc.setOper(WalletOperEnum.FROZEN);
            walletService.updateAddFrozen(operEtcc);

            RedemptionEntity redemptionEntity = new RedemptionEntity();
            redemptionEntity.setTotal(operEtcc.getAmount());
            redemptionEntity.setUserId(investmentOrderEntity.getUserId());
            redemptionEntity.setOrderId(investmentOrderEntity.getId());
            redemptionEntity.setStatus(1);
            redemptionEntity.setType(1);
            redemptionEntity.setStartTime(DateUtil.getLaterDayDate(investmentEntity.getProfitDay()).getTime());
            redemptionEntity.setRate(investmentEntity.getProfitRate());
            redemptionEntity.setSuccessAmount(BigDecimal.ZERO);
            redemptionEntity.setCreateTime(new Date());
            redemptionEntity.setUpdateTime(new Date());
            if (!redemptionService.insert(redemptionEntity)) {
                throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
            }

            WalletEntity walletEntity = walletService.selectByUserId(investmentOrderEntity.getUserId());

            WalletOper walletOper = new WalletOper();
            walletOper.setUserId(investmentOrderEntity.getUserId());
            walletOper.setAmount(profitCash);
            walletOper.setRemark("到期转ETCC");
            walletOper.setOper(WalletOperEnum.ADD);
            if (walletEntity != null) {
                walletOper.setId(walletEntity.getId());
            }
            walletService.updateWallet(walletOper);
        }

        return 1;
    }


    @Override
    @Transactional
    public Integer updateInvestment() {
        InvestmentEntity investmentEntity = investmentService.selectEndTimeByOne();
        if (investmentEntity == null) {
            return 1;
        }
        int loopSize = 1;
        int bacheSize = 100;
        Page<UserEntity> fuserPage = new Page<UserEntity>(loopSize, bacheSize);
        List<UserEntity> listUser = userService.selectPageFilter(fuserPage, "");
        while (true) {
            try {
                for (UserEntity userEntity : listUser) {
                    Map<String, BigDecimal> intro = getIntro(userEntity.getId(), investmentEntity.getId());

                    BigDecimal introNumber = intro.get("introNumber");
                    BigDecimal downNumber = intro.get("downNumber");
                    BigDecimal number = BigDecimal.ZERO;
                    if (downNumber.compareTo(BigDecimal.ZERO) == 0) {
                        number = introNumber;
                    } else {
                        number = introNumber.compareTo(downNumber) == 1 ? downNumber : introNumber;
                    }

                    if (number.compareTo(BigDecimal.ZERO) == 0) {
                        continue;
                    }

                    BigDecimal dynamicCas = MathUtil.mul(number, MathUtil.div(investmentEntity.getDynamicCash(), new BigDecimal("100")));
                    BigDecimal dynamicEtcc = MathUtil.mul(number, MathUtil.div(investmentEntity.getDynamicEtcc(), new BigDecimal("100")));

                    DynamicEntity dynamicEntity = new DynamicEntity();
                    dynamicEntity.setUserId(userEntity.getId());
                    dynamicEntity.setOrderId(investmentEntity.getId());
                    dynamicEntity.setTotal(number);
                    dynamicEntity.setStatus(1);
                    dynamicEntity.setCashRate(investmentEntity.getDynamicCash());
                    dynamicEntity.setEtccRate(investmentEntity.getDynamicEtcc());
                    dynamicEntity.setCreateTime(new Date());
                    if (!dynamicService.insert(dynamicEntity)) {
                        throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
                    }

                    WalletOper operEtcc = new WalletOper();
                    operEtcc.setUserId(userEntity.getId());
                    operEtcc.setAmount(dynamicEtcc);
                    operEtcc.setRemark("总动态奖励转ETCC");
                    operEtcc.setOper(WalletOperEnum.FROZEN);
                    walletService.updateAddFrozen(operEtcc);

                    RedemptionEntity redemptionEntity = new RedemptionEntity();
                    redemptionEntity.setTotal(dynamicEtcc);
                    redemptionEntity.setUserId(userEntity.getId());
                    redemptionEntity.setOrderId(investmentEntity.getId());
                    redemptionEntity.setStatus(1);
                    redemptionEntity.setType(3);
                    redemptionEntity.setStartTime(DateUtil.getLaterDayDate(investmentEntity.getDynamicDay()).getTime());
                    redemptionEntity.setRate(investmentEntity.getDynamicRate());
                    redemptionEntity.setSuccessAmount(BigDecimal.ZERO);
                    redemptionEntity.setCreateTime(new Date());
                    redemptionEntity.setUpdateTime(new Date());
                    if (!redemptionService.insert(redemptionEntity)) {
                        throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
                    }

                    WalletEntity walletEntity = walletService.selectByUserId(userEntity.getId());

                    WalletOper walletOper = new WalletOper();
                    walletOper.setUserId(userEntity.getId());
                    walletOper.setAmount(dynamicCas);
                    walletOper.setRemark("总动态奖励转ETCC");
                    walletOper.setOper(WalletOperEnum.ADD);
                    if (walletEntity != null) {
                        walletOper.setId(walletEntity.getId());
                    }

                    walletService.updateWallet(walletOper);

                    Thread.sleep(500);
                }
                loopSize++;
                fuserPage = new Page<UserEntity>(loopSize, bacheSize);
                listUser = userService.selectPageFilter(fuserPage, "");
                if (listUser == null || listUser.isEmpty()) {
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        Integer result = investmentService.updateDynamicStatus(investmentEntity.getId());
        if (result <= 0) {
            throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
        }

        return 1;
    }

    @Override
    @Transactional
    public Integer updateLeaderInvestment() {
        InvestmentEntity investmentEntity = investmentService.selectEndTimeByDynamic();
        if (investmentEntity == null) {
            return 1;
        }
        int loopSize = 1;
        int bacheSize = 100;
        Page<UserEntity> fuserPage = new Page<UserEntity>(loopSize, bacheSize);
        List<UserEntity> listUser = userService.selectPageFilter(fuserPage, " where leader=1 order by id desc ");
        while (true) {
            try {
                for (UserEntity userEntity : listUser) {


                    /*BigDecimal number = BigDecimal.ZERO;
                    List<UserEntity> userEntityList = userService.selectIntroUserId(userEntity.getId());
                    for (UserEntity user : userEntityList) {
                        BigDecimal total = dynamicService.selectByTotal(user.getId(),investmentEntity.getId());
                        number = MathUtil.add(number, total);
                    }*/

                    Map<String, BigDecimal> intro = getIntro(userEntity.getId(), investmentEntity.getId());
                    BigDecimal number = intro.get("number");
                    if (number.compareTo(BigDecimal.ZERO) == 0) {
                        continue;
                    }

                    DynamicLogEntity dynamicLogEntity = new DynamicLogEntity();
                    dynamicLogEntity.setCreateTime(new Date());
                    dynamicLogEntity.setUserId(userEntity.getId());
                    dynamicLogEntity.setStatus(0);
                    dynamicLogEntity.setTotal(number);
                    dynamicLogEntity.setOrderId(investmentEntity.getId());
                    dynamicLogEntity.setNumber(BigDecimal.ZERO);
                    dynamicLogEntity.setRate(userEntity.getLeaderRate());
                    if (!dynamicLogService.insert(dynamicLogEntity)) {
                        throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
                    }
                    Thread.sleep(500);
                }
                loopSize++;
                fuserPage = new Page<UserEntity>(loopSize, bacheSize);
                listUser = userService.selectPageFilter(fuserPage, "");
                if (listUser == null || listUser.isEmpty()) {
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        Integer result = investmentService.updateEndTimeByDynamicStatus(investmentEntity.getId());
        if (result <= 0) {
            throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
        }

        return 1;
    }

    public Map<String, BigDecimal> getIntro(Integer userId, Integer investmentId) {
        Map<String, BigDecimal> map = new HashMap<>(10);
        map.put("introNumber", BigDecimal.ZERO);
        map.put("downNumber", BigDecimal.ZERO);
        map.put("number", BigDecimal.ZERO);
        Map<String, BigDecimal> introUser = getIntroUser(investmentId, userId, userId, map);
        return introUser;
    }

    public Map<String, BigDecimal> getIntroUser(Integer investmentId, Integer oldUserId, Integer userId, Map<String, BigDecimal> str) {
        List<UserEntity> list = userService.selectIntroUserId(userId);
        if (list != null && list.size() > 0) {
            if (!oldUserId.equals(userId)) {
                BigDecimal count = str.get("downNumber");
                BigDecimal number = BigDecimal.ZERO;

                BigDecimal dynamicCount = str.get("number");
                BigDecimal dynamicNumber = BigDecimal.ZERO;

                for (UserEntity userEntity : list) {
                    BigDecimal total = investmentLogService.selectInvestmentTotal(investmentId, userEntity.getId());
                    number = MathUtil.add(number, total);

                    BigDecimal dynamicTotal = dynamicService.selectByTotal(userEntity.getId(), investmentId);
                    dynamicNumber = MathUtil.add(dynamicNumber, dynamicTotal);
                }
                count = MathUtil.add(number, count);
                str.put("downNumber", count);

                dynamicCount = MathUtil.add(dynamicNumber, dynamicCount);
                str.put("number", dynamicCount);
            } else {
                BigDecimal count = str.get("introNumber");
                BigDecimal number = BigDecimal.ZERO;

                BigDecimal dynamicCount = str.get("number");
                BigDecimal dynamicNumber = BigDecimal.ZERO;

                for (UserEntity userEntity : list) {
                    BigDecimal total = investmentLogService.selectInvestmentTotal(investmentId, userEntity.getId());
                    number = MathUtil.add(number, total);

                    BigDecimal dynamicTotal = dynamicService.selectByTotal(userEntity.getId(), investmentId);
                    dynamicNumber = MathUtil.add(dynamicNumber, dynamicTotal);
                }
                count = MathUtil.add(number, count);
                str.put("introNumber", count);

                dynamicCount = MathUtil.add(dynamicNumber, dynamicCount);
                str.put("number", dynamicCount);
            }
            for (int i = 0; i < list.size(); i++) {
                str = getIntroUser(investmentId, oldUserId, list.get(i).getId(), str);
            }
        }
        return str;
    }


    @Override
    @Transactional
    public Integer updateIntroInvestmentOrder() {

        List<InvestmentOrderEntity> selectInvestmentOrderList = baseMapper.selectInvestmentOrderList();
        for (InvestmentOrderEntity investmentOrderEntity : selectInvestmentOrderList) {
            introInvestmentOrder(investmentOrderEntity);
        }
        return 1;
    }

    public Integer introInvestmentOrder(InvestmentOrderEntity investmentOrderEntity) {
        UserEntity userEntity = userService.selectById(investmentOrderEntity.getUserId());
        Integer count = 0;

        if (userEntity.getIntroUserid() != null) {
            count = getIntroUser(investmentOrderEntity, userEntity.getIntroUserid(), count);
        }

        Integer result = baseMapper.updateIntroStatus(investmentOrderEntity.getId());
        if (result <= 0) {
            throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
        }

        return count;
    }

    public Integer getIntroUser(InvestmentOrderEntity investmentOrder, Integer userId, Integer count) {
        UserEntity userEntity = userService.selectById(userId);
        InvestmentOrderEntity investmentOrderEntity = this.selectInvestmentOrderByInvestmentAndUser(investmentOrder.getInvestmentId(), userId);

        InvestmentEntity investmentEntity = investmentService.selectById(investmentOrder.getInvestmentId());
        String[] introlTradeRates = sysConfigService.getValue("introlTradeRate").split("#");
        String introlTradeRate = count >= introlTradeRates.length ? introlTradeRates[introlTradeRates.length - 1] : introlTradeRates[count];

        if (investmentOrderEntity != null) {

            BigDecimal number = investmentOrder.getNumber().compareTo(investmentOrderEntity.getNumber()) == 1 ? investmentOrderEntity.getNumber() : investmentOrder.getNumber();
            number = MathUtil.mul(number, MathUtil.div(investmentEntity.getProfitCash(), new BigDecimal("100")));
            BigDecimal introlRate = MathUtil.div(new BigDecimal(introlTradeRate), new BigDecimal("100"));
            BigDecimal introlNumber = MathUtil.mul(number, introlRate);

            InvestmentLogEntity investmentLog = new InvestmentLogEntity();
            investmentLog.setCreateTime(new Date());
            investmentLog.setUserId(userId);
            investmentLog.setLevel(count);
            investmentLog.setOrderId(investmentOrder.getId());
            investmentLog.setRate(new BigDecimal(introlTradeRate));
            investmentLog.setTotal(introlNumber);
            if (!investmentLogService.insert(investmentLog)) {
                throw new ZeroResultException(new JsonResultVo(message.getMessage("error_info_zero")));
            }
            WalletOper oper = new WalletOper();
            WalletEntity walletEntity = walletService.selectByUserId(userId);
            oper.setUserId(userId);
            oper.setAmount(introlNumber);
            oper.setRemark("报单奖励");
            oper.setOper(WalletOperEnum.ADD);
            if (walletEntity != null) {
                oper.setId(walletEntity.getId());
            }
            walletService.updateWallet(oper);
        }

        count++;
        if (userEntity.getIntroUserid() != null) {
            getIntroUser(investmentOrder, userEntity.getIntroUserid(), count);
        }

        return count;
    }


    @Override
    public JsonResultVo selectInvestmentOrderByUserId(Integer userId) {
        List<InvestmentOrderEntity> orderEntityList = baseMapper.selectInvestmentOrderByUserId(userId);
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (InvestmentOrderEntity investmentOrderEntity : orderEntityList) {
            Map<String, Object> map = new HashMap<>(10);
            map.put("id", investmentOrderEntity.getId());
            map.put("investmentId", investmentOrderEntity.getInvestmentId());
            map.put("number", investmentOrderEntity.getNumber());
            map.put("invest", investmentOrderEntity.getInvest());
            map.put("orderId", investmentOrderEntity.getOrderId());
            map.put("startTime", DateUtil.format(DateUtil.ZH_CN_DATE_TIME_STAMP, investmentOrderEntity.getStartTime()));
            map.put("endTime", DateUtil.format(DateUtil.ZH_CN_DATE_TIME_STAMP, investmentOrderEntity.getEndTime()));
            map.put("status", investmentOrderEntity.getStatus());
            mapList.add(map);
        }
        return new JsonResultVo(message.getMessage("success"), mapList, 0);
    }

    @Override
    public JsonResultVo selectUserInvestmentOrder(Integer userId) {
        InvestmentOrderEntity investmentOrderEntity = baseMapper.selectUserInvestmentOrder(userId);
        List<Map<String, Object>> mapList = new ArrayList<>(10);
        Map<String, Object> map = new HashMap<>(2);

        if (investmentOrderEntity != null) {
            InvestmentEntity investmentEntity = investmentService.selectById(investmentOrderEntity.getInvestmentId());
            BigDecimal profitCash = MathUtil.mul(investmentOrderEntity.getNumber(), MathUtil.div(investmentEntity.getProfitCash(), new BigDecimal("100")));
            BigDecimal profitIntegral = MathUtil.mul(investmentOrderEntity.getNumber(), MathUtil.div(investmentEntity.getProfitIntegral(), new BigDecimal("100")));
            BigDecimal profitEtcc = MathUtil.mul(investmentOrderEntity.getNumber(), MathUtil.div(investmentEntity.getProfitEtcc(), new BigDecimal("100")));
            map.put("name", "我的投资");
            map.put("val", investmentOrderEntity.getNumber());
            mapList.add(map);

            map = new HashMap<>(2);
            map.put("name", "我的收益日");
            map.put("val", DateUtil.format(DateUtil.ZH_CN_DATE, investmentOrderEntity.getEndTime()));
            mapList.add(map);

            map = new HashMap<>(2);
            map.put("name", "本期收益");
            map.put("val", profitCash);
            mapList.add(map);

            map = new HashMap<>(2);
            map.put("name", "本期商场收益");
            map.put("val", profitIntegral);
            mapList.add(map);

            map = new HashMap<>(2);
            map.put("name", "ETCC锁仓");
            map.put("val", profitEtcc);
            mapList.add(map);

        }else {
            map.put("name", "我的投资");
            map.put("val", 0);
            mapList.add(map);

            map = new HashMap<>(2);
            map.put("name", "我的收益日");
            map.put("val", 0);
            mapList.add(map);

            map = new HashMap<>(2);
            map.put("name", "本期收益");
            map.put("val", 0);
            mapList.add(map);

            map = new HashMap<>(2);
            map.put("name", "本期商场收益");
            map.put("val", 0);
            mapList.add(map);

            map = new HashMap<>(2);
            map.put("name", "ETCC锁仓");
            map.put("val", 0);
            mapList.add(map);
        }

        return new JsonResultVo(message.getMessage("success"), mapList, 0);
    }
}
